package com.drink.yan.svc.service;

import com.alibaba.fastjson.JSONObject;
import com.alicp.jetcache.anno.Cached;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.drink.yan.core.mapper.YanActivityMapper;
import com.drink.yan.core.mapper.YanActivityUserMapper;
import com.drink.yan.intf.define.YanActivityStatusE;
import com.drink.yan.intf.define.YanCommissionStatusE;
import com.drink.yan.intf.define.YanCommissionTypeE;
import com.drink.yan.intf.define.YanUserTypeE;
import com.drink.yan.intf.entity.YanActivity;
import com.drink.yan.intf.entity.YanActivityUser;
import com.drink.yan.intf.entity.YanCommission;
import com.drink.yan.intf.entity.YanUserBind;
import com.drink.yan.intf.vo.*;
import com.drink.yan.web.rest.req.cmd.ApplyActivityCmd;
import com.drink.yan.web.rest.req.cmd.CancelActivityCmd;
import com.drink.yan.web.rest.req.cmd.EndActivityCmd;
import com.drink.yan.web.rest.req.qry.PageActivityQry;
import com.drink.yan.web.rest.req.qry.PageMyActivityQry;
import com.meta.act.app.service.ISysConfigService;
import com.meta.act.app.service.ISysDictTypeService;
import com.meta.act.app.service.ISysUserService;
import com.meta.framework.act.entity.SysUser;
import com.meta.framework.common.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.asm.Advice;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * java类简单作用描述
 *
 * @Title:
 * @Package: com.drink.yan.svc.service.
 * @Author: M.simple
 * @Remark: The modified content
 * @CreateDate: 2023/11/24 20:44
 * @Version: v2.0
 */
@Slf4j
@Service
public class YanActivityService extends ServiceImpl<YanActivityMapper, YanActivity> {

    @Resource
    private YanActivityUserMapper yanActivityUserMapper;

    @Resource
    private YanActivityMapper yanActivityMapper;

    @Resource
    private YanUserService yanUserService;

    @Resource
    private YanCommissionService yanCommissionService;

    @Resource
    private ISysUserService iSysUserService;

    @Resource
    private ISysDictTypeService iSysDictTypeService;

    @Resource
    private ISysConfigService iSysConfigService;



    public List<ActivityVo> listActivityByUser(PageMyActivityQry qry) {

        List<ActivityVo> activityVos = yanActivityMapper.listActivity(qry);
        activityVos.forEach(x->{
            x.setActivityImages(JSONObject.parseArray(x.getActivityImagesStr(), String.class));
        });
        return activityVos;
    }

    //@Cached(name = "yan:activity:list:", key = "#qry", expire = 60)
    public List<ActivityVo> listActivity(PageActivityQry qry) {


        LambdaQueryWrapper<YanActivity> queryWrapper = new LambdaQueryWrapper<>();
        //热门活动逻辑：未结束的活动，根据时间取最近的2个
        if("hot".equals(qry.getQueryType())){
//            queryWrapper.le(YanActivity::getStartTime, LocalDateTime.now());
//            queryWrapper.gt(YanActivity::getEndTime, LocalDateTime.now());
            queryWrapper.orderByAsc(YanActivity::getStartTime);
        }else {
            queryWrapper.eq(Objects.nonNull(qry.getQueryType()), YanActivity::getActivityType, qry.getQueryType());
        }
        queryWrapper.like(Objects.nonNull(qry.getActivityName()), YanActivity::getActivityName, qry.getActivityName());
        queryWrapper.like(Objects.nonNull(qry.getActivityAdress()), YanActivity::getActivityAdress, qry.getActivityAdress());
        queryWrapper.in(Objects.nonNull(qry.getActivityTypeList()), YanActivity::getActivityType, qry.getActivityTypeList());
        queryWrapper.in(Objects.nonNull(qry.getActivityStatusList()), YanActivity::getActivityStatus, qry.getActivityStatusList());
        queryWrapper.ge(Objects.nonNull(qry.getStartTime()), YanActivity::getEndTime, qry.getStartTime());
        queryWrapper.le(Objects.nonNull(qry.getEndTime()), YanActivity::getStartTime, qry.getEndTime());
        queryWrapper.orderByDesc(YanActivity::getActivityId);

        Map<String, String> activity_status = iSysDictTypeService.selectDictMapByType("activity_status");
        List<ActivityVo> yanActivities = yanActivityMapper.listActivityVo(qry);

        yanActivities.forEach(activityVo->{
            activityVo.setActivityStatusName(activity_status.getOrDefault(activityVo.getActivityStatus(), ""));
            ActivityVo activityDetail = getActivityDetail(activityVo.getActivityId());
            activityVo.setUserVoList(activityDetail.getUserVoList());
            activityVo.setActivityImages(activityDetail.getActivityImages());
            activityVo.setActivityLabels(activityDetail.getActivityLabels());
            activityVo.setSignNum(activityDetail.getSignNum());
            activityVo.setUserNum(activityDetail.getUserNum());
            activityVo.setApplyNum(activityDetail.getApplyNum());
            activityVo.setCreateByName(activityDetail.getCreateByName());
            activityVo.setScopeValue(activityDetail.getScopeValue());
        });

        return yanActivities;
    }

    public ActivityVo applyActivity(ApplyActivityCmd cmd) {
        YanActivityUser yanActivityUser = new YanActivityUser();
        yanActivityUser.setActivityId(cmd.getActivityId());
        yanActivityUser.setUserId(cmd.getUserId());
        yanActivityUser.setChannel(cmd.getChannel());
        YanUserBind yanUserBind = yanUserService.getBusinessKeyBind(cmd.getActivityId(), cmd.getUserId());
        if(Objects.nonNull(yanUserBind)){
            yanActivityUser.setShareUserId(yanUserBind.getTargetUid());
        }
        yanActivityUser.setApplyStatus("yes");
        yanActivityUser.setCreateBy(SecurityUtils.getUserId());
        yanActivityUser.setCreateTime(LocalDateTime.now());
        yanActivityUser.setApplyTime(LocalDateTime.now());
        yanActivityUserMapper.insert(yanActivityUser);
        return getActivityDetail(yanActivityUser.getActivityId());
    }

    public ActivityVo signActivity(ApplyActivityCmd cmd) {


        //签到成功后，产生给分享者的佣金
        YanUserBind yanUserBind = yanUserService.getBusinessKeyBind(cmd.getActivityId(), cmd.getUserId());
        if(Objects.isNull(yanUserBind)){
            log.info("this maybe a exception case, because commission can not apply, activityId:{}", cmd.getActivityId());
        }
        YanActivityUser activityUser = getActivityUser(cmd.getActivityId(), cmd.getUserId());
        if(Objects.isNull(activityUser) || Objects.isNull(activityUser.getId())){
            YanActivityUser yanActivityUser = new YanActivityUser();

            yanActivityUser.setActivityId(cmd.getActivityId());
            yanActivityUser.setUserId(cmd.getUserId());
            yanActivityUser.setChannel(cmd.getChannel());
            if(Objects.nonNull(yanUserBind)){
                yanActivityUser.setShareUserId(yanUserBind.getTargetUid());
            }
            yanActivityUser.setSignStatus("yes");
            yanActivityUser.setCreateBy(SecurityUtils.getUserId());
            yanActivityUser.setCreateTime(LocalDateTime.now());
            //yanActivityUser.setApplyTime(LocalDateTime.now());
            yanActivityUser.setSignTime(LocalDateTime.now());
            yanActivityUserMapper.insert(yanActivityUser);
            activityUser = yanActivityUser;
        }else {
            activityUser.setSignStatus("yes");
            activityUser.setSignTime(LocalDateTime.now());
            activityUser.setUpdateTime(LocalDateTime.now());
            yanActivityUserMapper.updateById(activityUser);
        }

        if(Objects.nonNull(yanUserBind)){
            ActivityVo activityDetail = getActivityDetail(cmd.getActivityId());
            YanCommission yanCommission = new YanCommission();
            yanCommission.setBusinessKey(activityDetail.getActivityId());
            yanCommission.setBusinessSubKey(activityUser.getId());
            yanCommission.setStudentId(cmd.getUserId());
            yanCommission.setUserId(yanUserBind.getTargetUid());
            yanCommission.setCommissionType(YanCommissionTypeE.activity_sign.getCode());
            yanCommission.setCommissionStatus(YanCommissionStatusE.in_account.getCode());
            yanCommission.setCommissionTypeName(YanCommissionTypeE.activity_sign.getRemark());
            yanCommission.setCommissionName(activityDetail.getActivityName());
            yanCommission.setBusinessAmount(BigDecimal.ZERO);
            yanCommission.setUserType(YanUserTypeE.agency.getCode());
            yanCommissionService.generateCommission(yanCommission);
        }

        return getActivityDetail(cmd.getActivityId());

    }

    public YanActivityUser getActivityUser(Long activityId, Long userId) {
        LambdaQueryWrapper<YanActivityUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(YanActivityUser::getActivityId, activityId)
                .eq(YanActivityUser::getUserId, userId)
                .eq(YanActivityUser::getDelFlag, 0);

        return yanActivityUserMapper.selectOne(queryWrapper);
    }

    public ActivityVo getActivityDetail(Long activityId) {

        YanActivity yanActivity = this.yanActivityMapper.selectById(activityId);
        SysUser sysUser = iSysUserService.selectUserById(yanActivity.getCreateBy());
        ActivityVo activityVo = yanActivity.transform(ActivityVo.class);
        if(Objects.nonNull(sysUser)){
            activityVo.setCreateByName(sysUser.getNickName());
        }
        List<ActivityUserVo> list = yanActivityMapper.listUserDetail(activityId);
        String baseUserNumStr = this.iSysConfigService.selectConfigByKey("yan.activity.base.userNum");

        Integer baseUserNum = 0;
        try{
            baseUserNum = Integer.valueOf(baseUserNumStr);
        }catch (Exception e){
            log.error("=== yan config error, config key is {}", "yan.activity.base.userNum");
        }

        activityVo.setUserVoList(list);
        if(!CollectionUtils.isEmpty(list)){
            activityVo.setUserNum(list.size() + baseUserNum);
        }else{
            activityVo.setUserNum(baseUserNum);
        }
        List<ActivityUserVo> applyList = list.stream().filter(x -> "yes".equals(x.getApplyStatus())).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(applyList)){
            activityVo.setApplyNum(applyList.size());
        }
        List<ActivityUserVo> signList = list.stream().filter(x -> "yes".equals(x.getSignStatus())).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(signList)){
            activityVo.setSignNum(signList.size());
        }
        return activityVo;
    }

    public ActivityVo getActivityExportDetail(Long activityId) {

        YanActivity yanActivity = this.yanActivityMapper.selectById(activityId);
        ActivityVo activityVo = yanActivity.transform(ActivityVo.class);
        List<ActivityStudentVo> list = yanActivityMapper.listExportUserDetail(activityId);
        activityVo.setExportStudentVos(list);
        return activityVo;
    }

    public YanActivity saveActivity(YanActivity yanActivity) {

        yanActivity = saveActivity(yanActivity, true);

        return yanActivity;
    }

    public YanActivity saveActivity(YanActivity yanActivity, boolean loginFlag) {
        if(Objects.isNull(yanActivity.getActivityId())){
            yanActivity.setActivityStatus(YanActivityStatusE.ready.getCode());
            yanActivity.setCreateBy(SecurityUtils.getUserId());
            yanActivity.setCreateTime(LocalDateTime.now());
            this.save(yanActivity);
        }else {
            ActivityVo activityDetail = getActivityDetail(yanActivity.getActivityId());
            Optional.ofNullable(yanActivity.getActivityName()).ifPresent(activityDetail::setActivityName);
            Optional.ofNullable(yanActivity.getActivityAdress()).ifPresent(activityDetail::setActivityAdress);
            Optional.ofNullable(yanActivity.getActivityContent()).ifPresent(activityDetail::setActivityContent);
            Optional.ofNullable(yanActivity.getActivityImages()).ifPresent(activityDetail::setActivityImages);
            Optional.ofNullable(yanActivity.getActivityLabels()).ifPresent(activityDetail::setActivityLabels);
            Optional.ofNullable(yanActivity.getActivityName()).ifPresent(activityDetail::setActivityName);
            Optional.ofNullable(yanActivity.getActivityStatus()).ifPresent(activityDetail::setActivityStatus);
            Optional.ofNullable(yanActivity.getStartTime()).ifPresent(activityDetail::setStartTime);
            Optional.ofNullable(yanActivity.getEndTime()).ifPresent(activityDetail::setEndTime);
            Optional.ofNullable(yanActivity.getScopeType()).ifPresent(activityDetail::setScopeType);
            Optional.ofNullable(yanActivity.getScopeValue()).ifPresent(activityDetail::setScopeValue);

            if(loginFlag){
                activityDetail.setUpdateBy(SecurityUtils.getUserId());
            }
            activityDetail.setUpdateTime(LocalDateTime.now());
            this.updateById(activityDetail);
            yanActivity = activityDetail;
        }
        return yanActivity;
    }

    public Boolean deleteActivity(Long activityId) {
        this.baseMapper.deleteById(activityId);

        return true;
    }

    public List<ActivityVo> listShareActivity(PageActivityQry qry) {

        List<ActivityVo> activityVos = this.baseMapper.listShareActivity(qry);
        activityVos.forEach(x->{
            x.setActivityImages(JSONObject.parseArray(x.getActivityImagesStr(), String.class));
        });
        return activityVos;
    }

    public List<ActivityVo> listNowActivity(PageActivityQry qry) {

        UserVo yanUserVo = yanUserService.getYanUserVo(qry.getUserId());
        UserAgencyVo yanUserAgency = yanUserVo.getYanUserAgency();
        if(Objects.nonNull(yanUserAgency)){
            qry.setSchoolArea(yanUserAgency.getCurrentSchId());
        }

        List<ActivityVo> activityVos = this.baseMapper.listNowActivity(qry);
        activityVos.forEach(x->{
            x.setActivityImages(JSONObject.parseArray(x.getActivityImagesStr(), String.class));
            x.setScopeValue(JSONObject.parseArray(x.getScopeValueStr(), Long.class));
        });
        return activityVos;
    }

    public YanActivity cancelActivity(CancelActivityCmd cmd) {

        ActivityVo activityDetail = getActivityDetail(cmd.getActivityId());

        if(YanActivityStatusE.ready.getCode().equals(activityDetail.getActivityStatus())){
            activityDetail.setActivityStatus(YanActivityStatusE.cancelled.getCode());
        }
        activityDetail.setCreateBy(SecurityUtils.getUserId());
        saveActivity(activityDetail);

        return activityDetail;
    }

    public List<ActivityUserVo> listUserActivity(PageMyActivityQry qry) {
        return this.baseMapper.listUserActivity(qry);
    }

    public ActivityVo endActivity(EndActivityCmd cmd) {

        ActivityVo activityDetail = getActivityDetail(cmd.getActivityId());

        if(!YanActivityStatusE.cancelled.getCode().equals(activityDetail.getActivityStatus())){
            activityDetail.setActivityStatus(YanActivityStatusE.ended.getCode());
        }
        //activityDetail.setCreateBy(SecurityUtils.getUserId());
        saveActivity(activityDetail);

        return activityDetail;
    }
}
